/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * Licensed under Simplified BSD License
 *
 *
 * @author: jin Chen 
 * @date: Dec 7, 2005$
 * @version: 1.0
 */
package edu.psu.geovista.app.gmatrix.data;

import edu.psu.geovista.app.gmatrix.toolkit.MatrixLoggerMgr;

import javax.swing.table.DefaultTableModel;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JRowHeadDfTableModel extends DefaultTableModel {
    private static final Logger logger=Logger.getLogger(JRowHeadDfTableModel.class.getName());
     protected Vector rowIdentifiers;

    public JRowHeadDfTableModel() {
         super((Vector) null, 0);
        initRowIdentifiers(0);
    }

    /*  public void addRow(Object rowName, Vector rowData)
    {
        DefaultTableModel.super.addRow(rowData);
        //rowIdentifiers.addElement(rowName);
    }*/
   protected void initRowIdentifiers(int numRows)
      {
          rowIdentifiers = new Vector(numRows);
          rowIdentifiers.setSize(numRows);
      }

      public String getRowName(int row)
      {
          String result;
          if (row < rowIdentifiers.size())
          {
              Object id = rowIdentifiers.elementAt(row);
              if (id == null)
              {
                  result = null;
              }
              else
              {
                  result = id.toString();
              }
          }
          else
          {
              result = null;
          }
          return result;
      }


     public void addRow(Vector rowData)
    {
        addRow(null, rowData);

    }
     public void addRow(Object[] rowData)
    {
        addRow(null, convertToVector(rowData));
    }
    public void addRow(Object rowName, Vector rowData) {
        /*rowIdentifiers.addElement(rowName);
	if (rowData != null) {
            int columnSize = rowData.size();
            if (columnSize > getRowCount()) {
	        dataVector.setSize(columnSize);
            }
	    justifyRows(0, getRowCount());
	    int newColumn = getColumnCount() - 1;
	    for(int i = 0; i < columnSize; i++) {
		  Vector row = (Vector)dataVector.elementAt(i);
		  row.setElementAt(rowData.elementAt(i), newColumn);
	    }
	}
        else {
	    justifyRows(0, getRowCount());
        }

        fireTableStructureChanged();*/
      // Vector arow = convertFloatToVector(values);


        if (this.getColumnCount() == 0){
            initColumnIdentifiers(rowData.size() );
        }
        else if (rowData.size()  != getColumnCount()){
            throw new IllegalArgumentException("Recordsets must have same number of dimensions (" + getColumnCount() + ")");
        }
        this.dataVector.add(rowData);
        rowIdentifiers.add(rowName);
         //printIds(rowIdentifiers);
        fireTableStructureChanged();
       // this.fireRowsInserted(this.getNumRecords(),this.getNumRecords());
    }
     private void printIds(Vector v){
        int i=0;
        for (Iterator iterator = v.iterator(); iterator.hasNext();) {
            String name = (String) iterator.next();
            System.out.println("row "+(i++)+" : "+name);

        }

    }

    protected  void initColumnIdentifiers(int colCount) {
        //values=new Vector(colCount);
         columnIdentifiers =new Vector(colCount);
                for (int i=0; i<colCount; i++){
            columnIdentifiers.add(null);
            //valueLabels.add(null);
        }
         //initMyNumDimensions(num,this.dataVector , this.columnIdentifiers);

     }

    /*private void initMyNumDimensions(int colCount,Vector values, Vector columnIdentifiers) {
        values=new Vector(colCount);
         columnIdentifiers =new Vector(colCount);
        //this.valueLabels =new Vector(colCount);

        for (int i=0; i<colCount; i++){
            columnIdentifiers.add(null);
            //valueLabels.add(null);
        }
    }*/

     public void removeRow(int row)
    {
        super.removeRow(row);
        rowIdentifiers.removeElementAt(row);
    }

    public void setRowIdentifiers(Object[] rownames){
        int rowCount = this.getRowCount();
        if(rownames.length !=rowCount){
           new IllegalArgumentException(this.getClass().getName() +" is passed a wrong length array");
        }

        this.rowIdentifiers.clear();

        for (int i=0;i<rownames.length ;i++){
             rowIdentifiers.add(rownames[i]);
        }
        this.fireTableStructureChanged();
    }

    public void clear(){
        dataVector.clear();
        this.rowIdentifiers.clear();
        this.columnIdentifiers.clear();
    }

   /*******************************************************************************************************
    *                move row/column
    *******************************************************************************************************/
    /**
     *  
     * @param start
     * @param end
     * @param to
     */
   public void moveRow(int start, int end, int to) {
       MatrixLoggerMgr.fine(logger," moveRow("+start+","+end+","+to+"  ---->");
       move(rowIdentifiers,start,end,to);
        if(logger.isLoggable(Level.FINE ) ){
            for (Iterator iterator = rowIdentifiers.iterator(); iterator.hasNext();) {
                String rowid = (String) iterator.next();
                System.out.println("       "+rowid);
            }

        }//if

       super.moveRow(start,end,to);
       MatrixLoggerMgr.fine(logger," moveRow () <--");
   }

    /**
     *  
     *  
     * @param dataVector
     * @param start  see DefaultTableModel.move()
     * @param end    see DefaultTableModel.move()
     * @param to     see DefaultTableModel.move()
     */
   protected static void move(Vector dataVector,int start, int end, int to){
       int shift = to - start;
    int first, last;
    if (shift < 0) {
        first = to;
        last = end;
    }
    else {
        first = start;
        last = to + end - start;
    }
        rotate(dataVector, first, last + 1, shift);
   }
    private static void rotate(Vector v, int a, int b, int shift) {
    int size = b - a;
    int r = size - shift;
    int g = gcd(size, r);
    for(int i = 0; i < g; i++) {
        int to = i;
        Object tmp = v.elementAt(a + to);
        for(int from = (to + r) % size; from != i; from = (to + r) % size) {
        v.setElementAt(v.elementAt(a + from), a + to);
        to = from;
        }
        v.setElementAt(tmp, a + to);
    }
    }
     private static int gcd(int i, int j) {
    return (j == 0) ? i : gcd(j, i%j);
    }
    /*******************************************************************************************************
     *                get
     *******************************************************************************************************/
    public String[] getRowNames(){
        int rowCount = this.getRowCount();
        String[] rns=new String[rowCount];
        for (int i=0;i<rns.length ;i++){
            String rowName = this.getRowName(i);
            rns[i]=rowName;
        }

        return rns;
    }
      public String[] getColumnNames(){
        int colCount = this.getColumnCount();
        String[] rns=new String[colCount];
        for (int i=0;i<rns.length ;i++){
            String colName = this.getColumnName(i);
            rns[i]=colName;
        }

        return rns;
    }

}
